package com.demo.client;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;

public class NotificationService extends Service {

	private static final String TAG = LogUtil.getClassName(NotificationService.class);
	
	private NotificationReceiver notifReceiver = null;
	private ConnectivityReceiver connectReceiver =null;
	
	private TelephonyManager teleManager = null;
	private PhoneStateChangeListener phoneStateChangeListener = null ;
	private String deviceId ;
	
	private SharedPreferences sharePreferences = null;
	
	private TaskSubmit taskSubmit = null;
	private TaskTracker taskTracker = null;
	
	private XmppManager xmppManager = null;
	private ExecutorService executorService = null;
	
	public NotificationService()
	{
		notifReceiver = new NotificationReceiver();
		connectReceiver = new ConnectivityReceiver();
		taskSubmit = new TaskSubmit(this);
		taskTracker = new TaskTracker(this);
		
		xmppManager = new XmppManager(this);
		executorService = Executors.newSingleThreadExecutor();
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "SERVER onCreate~~");
		
		teleManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
		deviceId = teleManager.getDeviceId();

		phoneStateChangeListener = new PhoneStateChangeListener(this);
		sharePreferences = getSharedPreferences(Constants.SHARE_PREFERENCE_NAME, Context.MODE_PRIVATE);
		
		Editor editor = sharePreferences.edit();
		editor.putString(Constants.PHONE_DEVICE_ID, deviceId);
		editor.commit();
		
	}

	
	@Override
	public void onStart(Intent intent, int startId) {
		
		registerNotificationReceiver();
		registerConnectivityReceiver();
		
		super.onStart(intent, startId);
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "SERVER onBind~~");
		return null;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "SERVER destory~~");
		stop();
	}
	
	private void stop()
	{
		unregisterNotificationReceiver();
		unregisterConnectivityReceiver();
		xmppManager.disConnect();
		executorService.shutdown();
	}
	
	public static Intent getIntent()
	{
		return new Intent().setAction("com.demo.client.NotificationService");
	}
	
	private void registerNotificationReceiver()
	{
		IntentFilter notificationFilter = new IntentFilter();
		notificationFilter.addAction(Constants.ACTION_CLEAR_NOTIFICATION);
		notificationFilter.addAction(Constants.ACTION_CLICK_NOTIFICATION);
		notificationFilter.addAction(Constants.ACTION_SHOW_NOTIFICATION);
		registerReceiver(notifReceiver, notificationFilter);
	}
	private void unregisterNotificationReceiver()
	{
		unregisterReceiver(notifReceiver);
	}

	private void registerConnectivityReceiver()
	{
		teleManager.listen(phoneStateChangeListener, 
				PhoneStateChangeListener.LISTEN_DATA_CONNECTION_STATE);
		IntentFilter filter = new IntentFilter();
		filter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
		registerReceiver(connectReceiver, filter);
	}
	private void unregisterConnectivityReceiver()
	{
		teleManager.listen(phoneStateChangeListener, phoneStateChangeListener.LISTEN_NONE);
		unregisterReceiver(connectReceiver);
	}
	public String getDeviceId() {
		return deviceId;
	}

	public void setDeviceId(String deviceId) {
		this.deviceId = deviceId;
	}
	
	/**
	 * 断线重连
	 */
	public void reconnect() {
		Log.d("TAG", "Notification is reconnect service...");
		
		taskSubmit.submit(new Runnable() {
			
			@Override
			public void run() {
				NotificationService.this.reconnect();
			}
		});
	}
	
	/**
	 * 连接
	 */
	public void connect()
	{
		Log.d(TAG, "Notification connect service...");
		taskSubmit.submit(new Runnable() {
			@Override
			public void run() {
				NotificationService.this.getXmppManager().connect();
			}
		});
	}
	
	/**
	 * 断开连接
	 */
	public void disconnect()
	{
		Log.d(TAG, "Notificatoin disconnect..");
		taskSubmit.submit(new Runnable() {
			
			@Override
			public void run() {
				NotificationService.this.getXmppManager().disConnect();
			}
		});
	}
	
	/**
	 * task  计数器
	 * 
	 * @author Administrator
	 *
	 */
	public class TaskTracker
	{
		private NotificationService notificationService = null;
		
		public int count = -1;
		
		public TaskTracker(NotificationService notificationService)
		{
			this.notificationService = notificationService;
			count = 0;
		}
		public void increase()
		{
			synchronized (notificationService.getTaskTracker()) {
				
				this.notificationService.getTaskTracker().count++;
			}
		}
		public void decrease() {
			synchronized (notificationService.getTaskTracker()) {
				this.notificationService.getTaskTracker().count--;
			}
		}
		
	}
	public class TaskSubmit
	{
		private NotificationService notificationService = null;
		
		public TaskSubmit(NotificationService notificationService) {
			this.notificationService = notificationService;
		}

		@SuppressWarnings("unchecked")
		public Future submit(Runnable task) {
			Future result = null;
			if(!notificationService.getExecutorService().isTerminated()
					&&!notificationService.getExecutorService().isShutdown()
					&&task!=null)
			{
				result = notificationService.getExecutorService().submit(task);
			}
			return result;
		}
	}
	
	public TaskSubmit getTaskSubmit() {
		return taskSubmit;
	}

	public void setTaskSubmit(TaskSubmit mTaskSubmit) {
		this.taskSubmit = mTaskSubmit;
	}
	
	public TaskTracker getTaskTracker() {
		return taskTracker;
	}

	public void setTaskTracker(TaskTracker taskTracker) {
		this.taskTracker = taskTracker;
	}

	public XmppManager getXmppManager() {
		return xmppManager;
	}

	public void setXmppManager(XmppManager xmppManager) {
		this.xmppManager = xmppManager;
	}

	public ExecutorService getExecutorService() {
		return executorService;
	}

	public void setExecutorService(ExecutorService executorService) {
		this.executorService = executorService;
	}
}
